import type { ComponentStyleIdType } from '../../types/interfaces'
import type { RefreshLoaderProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ToolKit } from '../../lib/utils/toolkit'
import { ComponentStyleId } from '../../types/constants'
import { styles } from './styles'
import { DEFAULT_REFRESH_LOADER_PROPS } from './types'

export class RefreshLoader extends UIComponent<RefreshLoaderProps> {
  id: string = 'refresh-loader'
  readonly description: string = '页面刷新加载组件'
  readonly styleId: string = ComponentStyleId[this.name]
  private isActive: boolean = false
  private overlayElement: HTMLElement | null = null
  private static instance: RefreshLoader

  get name(): ComponentStyleIdType {
    return 'RefreshLoader'
  }

  get className(): string {
    return 'refresh-loader'
  }

  constructor(props: RefreshLoaderProps) {
    super({
      ...DEFAULT_REFRESH_LOADER_PROPS,
      ...props,
    })

    // 注册样式
    this.registerStyles()

    this.render()
  }

  ELEMENT_SELECTORS = {}

  /**
   * 获取单例实例
   */
  static getInstance(props?: Partial<RefreshLoaderProps>): RefreshLoader {
    if (!RefreshLoader.instance) {
      RefreshLoader.instance = new RefreshLoader({ ...DEFAULT_REFRESH_LOADER_PROPS, ...props })
    }
    return RefreshLoader.instance
  }

  render(): void {
    if (this.overlayElement) {
      return
    }

    const { loadingText } = this.props

    const overlay = document.createElement('div')
    overlay.className = this.className
    overlay.innerHTML = `
      <div class="refresh-loader-spinner"></div>
      <div class="refresh-loader-text">${loadingText}</div>
    `

    $('#swal2-html-container').append(overlay)
    this.overlayElement = overlay
    this.updateVisibility()
  }

  /**
   * 显示加载动画
   */
  show(): void {
    this.isActive = true
    this.updateVisibility()
  }

  /**
   * 隐藏加载动画
   */
  hide(): void {
    this.isActive = false
    this.updateVisibility()
  }

  /**
   * 自动处理刷新前的显示和刷新后的隐藏
   * @param callback 刷新后执行的回调函数
   */
  wrapRefresh(callback: () => void): void {
    this.show()

    // 添加卸载前事件确保动画持续到页面卸载
    window.addEventListener('beforeunload', () => {
      this.show()
    })

    callback()
    ToolKit.ui.page.refreshPage()
  }

  private updateVisibility(): void {
    if (!this.overlayElement) {
      return
    }

    if (this.isActive) {
      this.overlayElement.classList.add('active')
    }
    else {
      this.overlayElement.classList.remove('active')
    }
    ToolKit.dom.setElementCssAttribute($('.swal2-actions'), this.isActive ? 'none' : 'flex')
  }

  getStyles(): string {
    return styles(this.props)
  }

  destroy(): void {
    super.destroy()
    this.overlayElement?.remove()
    this.overlayElement = null
  }
}

export function withRefreshLoader(callback?: () => void, props?: Partial<RefreshLoaderProps>): void {
  const loader = RefreshLoader.getInstance({ ...DEFAULT_REFRESH_LOADER_PROPS, ...props })
  loader.wrapRefresh(callback || (() => {}))
}
